#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
Caching NPSImage store.

Images are loaded on demand and are stored within the object for reload later.
This method replaces an original PySol method that on init preloaded all images.
"""

import os
import logging
import random

LOGGER = logging.getLogger('PySolFC.Utillib.Cache')

from ..viewlib.image import load_image
from .pathdb import PATH_DB
from ..settings import WIN_SYSTEM


class __ImageCache(object):
    """
    Caching Image store.

    Loads an image from disk or cache as an **Image** for use on the canvas.
    """
    __cache = {}
    __listdir = {'demo': [], 'pause': []}

    def __path(self, *args):
        """
        __path(self, *args) -> str

        Returns full normalized and joined path for **args** as path of parts.
        Calls **PATH_DB.find_image** locating path with 'images' subdir.
        """
        assert len(args) > 0
        LOGGER.info('Save to cache: %s', '-'.join(args))
        return PATH_DB.find_image(os.path.join(*args), 'images')

    def load(self, *args):
        """
        load(name, seed) -> NPSImage

        Get image from cache.

        Returns an **Image** from the cache based on **args** passed. Calls
        internal **__path** to locate image from **args** as parts of a path.
        """
        LOGGER.info('cache: %s', self.__cache)
        assert len(args) > 0
        key = tuple(args)
        if not key in self.__cache:
            LOGGER.info('Load from file: %s', "-".join(args))
            self.__cache[key] = image = load_image(self.__path(*args))
        else:
            LOGGER.info('Load from cache: %s', "-".join(args))
            image = self.__cache[key]
        LOGGER.info('cache: %s', self.__cache)
        return image

    def load_icon(self, icon):
        """
        load(name, seed) -> NPSImage

        Get icon name from cache.

        Returns an **Image** from the cache based on **icon** passed. Calls
        **load** after setting the theme path to **icon**.
        """
        if icon in ('error', 'info', 'question', 'warning'):
            return self.load('dialog',
                         ('default' if WIN_SYSTEM == 'win32' else 'bluecurve'),
                         icon)

    def load_toolbar_image(self, name, style, size):
        """
        load(name, seed) -> NPSImage

        Get toolbar image name from cache.

        Returns an **Image** from the cache based on **name**. Calls **load**
        after setting the style and size path to **name**. If style or size
        missing uses default and size.
        """
        path = os.path.join('images', 'toolbar', style, size)
        if PATH_DB.find_dir(style, subdirs=path, do_raise=False):
            image = self.load('toolbar', style, size, name)
        else:
            image = self.load('toolbar', 'default', size, name)
        return image

    def choice(self, name):
        """
        choice(name) -> NPSImage

        Get random choice image from cache.

        Returns an image from **name** list based on random.choice. Only works
        for logos being place on the canvas by 'pause' and 'demo'.
        """
        if not name in self.__listdir:
            return
        if self.__listdir[name] == []:
            self.__listdir[name] = [os.path.splitext(fn)[0] for fn in
                                os.listdir(PATH_DB.find_dir(name, 'images'))
                                if fn.startswith(name)]
        filelist = self.__listdir[name]
        return self.load(name, random.choice(filelist))

IMAGE_CACHE = __ImageCache()